package com.example.service.impl;

import com.example.dto.ExamPaperDTO;
import com.example.entity.ExamManualQuestion;
import com.example.entity.ExamPaper;
import com.example.entity.ExamQuestionBank;
import com.example.mapper.ExamManualQuestionMapper;
import com.example.mapper.ExamPaperMapper;
import com.example.mapper.ExamQuestionBankMapper;
import com.example.service.ExamManualQuestionService;
import com.example.service.ExamPaperService;
import com.example.vo.ExamPaperDetailVO;
import com.example.vo.ExamQuestionVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class ExamPaperServiceImpl implements ExamPaperService {

    @Autowired
    private ExamPaperMapper examPaperMapper;

    @Autowired
    private ExamManualQuestionMapper examManualQuestionMapper;

    @Autowired
    private ExamManualQuestionService examManualQuestionService;

    @Autowired
    private ExamQuestionBankMapper examQuestionBankMapper;

    //新增试卷
    @Override
    public void addExamPaper(ExamPaperDTO examPaperDTO) {
        ExamPaper paper = convertToExamPaper(examPaperDTO);
        setDefaultPaperValues(paper);

        // 计算总分
        BigDecimal totalScore = calculateTotalScore(examPaperDTO);
        paper.setTotalScore(totalScore);

        // 插入试卷数据并获取试卷 ID
        examPaperMapper.insertExamPaper(paper);

        // 批量插入新增的题目
        List<ExamManualQuestion> examManualQuestions = convertToExamManualQuestions(examPaperDTO, paper.getId());
        if (!examManualQuestions.isEmpty()) {
            examManualQuestionService.batchCreate(examManualQuestions);
        }
    }

    //更新试卷
    @Override
    public void updateExamPaper(ExamPaperDTO examPaperDTO) {
        ExamPaper paper = convertToExamPaper(examPaperDTO);
        // 保持试卷的默认信息，避免覆盖
        ExamPaper existingPaper = examPaperMapper.getExamPaperById(paper.getId());
        existingPaper.setPassScore(paper.getPassScore());
        existingPaper.setName(paper.getName());
        setDefaultPaperValues(existingPaper);  // 保持已有的默认信息

        // 计算总分，重新计算时考虑所有题目
        BigDecimal totalScore = calculateTotalScore(examPaperDTO, paper.getId());
        existingPaper.setTotalScore(totalScore);



        // 更新试卷信息
        examPaperMapper.updateExamPaper(existingPaper);

        // 处理新增、更新和删除题目
        handleExamQuestions(examPaperDTO, paper.getId());
    }

    //计算总分
    private BigDecimal calculateTotalScore(ExamPaperDTO examPaperDTO, Integer paperId) {
        BigDecimal totalScore = BigDecimal.ZERO;

        // 1. 获取试卷的所有现有题目
        List<ExamManualQuestion> existingQuestions = examManualQuestionMapper.selectExamManualQuestionsByQsnairId(paperId);

        // 2. 创建一个完整的题目列表，包含现有题目
        Map<Integer, ExamManualQuestion> questionMap = new HashMap<>();
        for (ExamManualQuestion existingQuestion : existingQuestions) {
            questionMap.put(existingQuestion.getQsId(), existingQuestion);
            totalScore = totalScore.add(new BigDecimal(String.valueOf(existingQuestion.getScore())));  // 添加现有题目分数
        }

        // 3. 处理新增题目（将新增题目添加到题目列表中）
        for (ExamPaperDTO.QuestionOperation question : examPaperDTO.getQuestions().getAdd()) {
            ExamManualQuestion manualQuestion = new ExamManualQuestion();
            manualQuestion.setQsId(question.getQuestionId());
            manualQuestion.setScore(question.getScore());
            manualQuestion.setOrderNumber(question.getOrderNumber());
            questionMap.put(question.getQuestionId(), manualQuestion);  // 添加新增题目到 map
            totalScore = totalScore.add(new BigDecimal(String.valueOf(question.getScore())));  // 加上新增题目的分数
            log.info("新增题目：{}，分数：{}", question.getQuestionId(), question.getScore());
        }

        // 4. 处理更新题目（根据更新的分数修改现有题目）
        for (ExamPaperDTO.QuestionOperation question : examPaperDTO.getQuestions().getUpdate()) {
            ExamManualQuestion existingQuestion = questionMap.get(question.getQuestionId());
            if (existingQuestion != null) {
                // 更新总分：减去旧分数，加上新分数
                totalScore = totalScore.subtract(new BigDecimal(String.valueOf(existingQuestion.getScore())));  // 减去旧分数
                existingQuestion.setScore(question.getScore());
                existingQuestion.setOrderNumber(question.getOrderNumber());
                totalScore = totalScore.add(new BigDecimal(String.valueOf(question.getScore())));  // 加上新分数
                log.info("更新题目：{}，新的分数：{}", question.getQuestionId(), question.getScore());
            }
        }

        // 5. 处理删除题目（从题目列表中删除被删除的题目）
        for (String questionId : examPaperDTO.getQuestions().getDelete()) {
            ExamManualQuestion removedQuestion = questionMap.remove(Integer.parseInt(questionId));  // 删除操作
            if (removedQuestion != null) {
                totalScore = totalScore.subtract(new BigDecimal(String.valueOf(removedQuestion.getScore())));  // 从总分中减去已删除题目的分数
                log.info("删除题目 ID：{}", questionId);
            }
        }

        // 6. 计算总分：最终的 totalScore 就是所有题目分数的和
        log.info("计算得到的总分：{}", totalScore);
        return totalScore;
    }





    // 设置试卷默认信息
    private void setDefaultPaperValues(ExamPaper paper) {
        if (paper.getPaperType() == null) paper.setPaperType(2);  // 默认试卷类型
        if (paper.getQuestionType() == null) paper.setQuestionType(1);  // 默认人工选题
        if (paper.getUnifyPaper() == null) paper.setUnifyPaper(1);  // 默认统一试卷
        if (paper.getQuestionOrder() == null) paper.setQuestionOrder(2);  // 默认题目顺序
        if (paper.getCreateName() == null) paper.setCreateName("Group4");  // 默认创建者
        LocalDateTime now = LocalDateTime.now();
        if (paper.getCreateTime() == null) paper.setCreateTime(now);  // 默认创建时间
        if (paper.getUpdateTime() == null) paper.setUpdateTime(now);  // 默认更新时间
    }

    private BigDecimal calculateTotalScore(ExamPaperDTO examPaperDTO) {
        BigDecimal totalScore = BigDecimal.ZERO;
        for (ExamPaperDTO.QuestionOperation question : examPaperDTO.getQuestions().getAdd()) {
            totalScore = totalScore.add(new BigDecimal(String.valueOf(question.getScore())));
        }
        return totalScore;
    }

    private List<ExamManualQuestion> convertToExamManualQuestions(ExamPaperDTO examPaperDTO, Integer paperId) {
        LocalDateTime now = LocalDateTime.now();
        List<ExamManualQuestion> examManualQuestions = new ArrayList<>();
        for (ExamPaperDTO.QuestionOperation question : examPaperDTO.getQuestions().getAdd()) {
            ExamManualQuestion manualQuestion = new ExamManualQuestion();
            manualQuestion.setQsId(question.getQuestionId());
            manualQuestion.setOrderNumber(question.getOrderNumber());
            manualQuestion.setQsnairId(paperId);
            manualQuestion.setScore(question.getScore());
            manualQuestion.setCreateTime(now);
            manualQuestion.setUpdateTime(now);
            examManualQuestions.add(manualQuestion);
        }
        return examManualQuestions;
    }

    private void handleExamQuestions(ExamPaperDTO examPaperDTO, Integer paperId) {
        LocalDateTime now = LocalDateTime.now();

        // 新增题目
        List<ExamManualQuestion> examManualQuestionsToAdd = convertToExamManualQuestions(examPaperDTO, paperId);
        if (!examManualQuestionsToAdd.isEmpty()) {
            examManualQuestionService.batchCreate(examManualQuestionsToAdd);
        }

        // 更新题目
        List<ExamManualQuestion> examManualQuestionsToUpdate = new ArrayList<>();
        for (ExamPaperDTO.QuestionOperation question : examPaperDTO.getQuestions().getUpdate()) {
            ExamManualQuestion manualQuestion = new ExamManualQuestion();
            manualQuestion.setQsId(question.getQuestionId());
            manualQuestion.setOrderNumber(question.getOrderNumber());
            manualQuestion.setQsnairId(paperId);
            manualQuestion.setScore(question.getScore());
            manualQuestion.setUpdateTime(now);
            examManualQuestionsToUpdate.add(manualQuestion);
        }
        if (!examManualQuestionsToUpdate.isEmpty()) {
            for (ExamManualQuestion manualQuestion : examManualQuestionsToUpdate) {
                examManualQuestionMapper.updateExamManualQuestionByPaperIdAndQsId(manualQuestion);
            }
        }

        // 删除题目
        List<String> deleteQuestions = examPaperDTO.getQuestions().getDelete();
        if (deleteQuestions != null && !deleteQuestions.isEmpty()) {
            Map<String, Object> params = new HashMap<>();
            params.put("qsnairId", paperId);
            log.info("paperId:{}", paperId);
            params.put("qsIds", deleteQuestions);
            log.info("deleteQuestions:{}", deleteQuestions);
            examManualQuestionMapper.batchDeleteExamManualQuestionsByPaperIdAndQsIds(params);
        }
    }

    // 根据试卷id删除试卷
    @Override
    public void deleteExamPaperById(Integer id) {
        examPaperMapper.deleteExamPaperById(id);
        examManualQuestionMapper.deleteExamManualQuestionByQsnairId(id);
    }




    // 分页查询
    @Override
    public List<ExamPaper> getExamPapersByPage(int pageNum, int pageSize) {
        int offset = (pageNum - 1) * pageSize;
        return examPaperMapper.getExamPapersByPage(offset, pageSize);
    }

    // 获取试卷总数
    @Override
    public long getTotalExamPapers() {
        return examPaperMapper.getTotalExamPapers();
    }

    // 根据试卷id获取试卷信息
    @Override
    public ExamPaperDetailVO getExamPaperDetailById(Integer paperId) {
        List<ExamManualQuestion> manualQuestions = examManualQuestionMapper.selectExamManualQuestionsByQsnairId(paperId);
        List<ExamQuestionVO> examQuestionVOS = convertToExamQuestionVOList(manualQuestions);

        ExamPaperDetailVO examPaperDetailVO = new ExamPaperDetailVO();
        ExamPaper examPaperExit = examPaperMapper.getExamPaperById(paperId);

        examPaperDetailVO.setPaperId(paperId);
        examPaperDetailVO.setPaperName(examPaperExit.getName());
        examPaperDetailVO.setPaperType(examPaperExit.getPaperType());
        examPaperDetailVO.setQuestionType(examPaperExit.getQuestionType());
        examPaperDetailVO.setQuestionOrder(examPaperExit.getQuestionOrder());
        examPaperDetailVO.setTotalScore(examPaperExit.getTotalScore());
        examPaperDetailVO.setBusiTypeId1(examPaperExit.getBusiTypeId1());
        examPaperDetailVO.setBusiTypeName1(examPaperExit.getBusiTypeName1());
        examPaperDetailVO.setBusiTypeId2(examPaperExit.getBusiTypeId2());
        examPaperDetailVO.setBusiTypeName2(examPaperExit.getBusiTypeName2());
        examPaperDetailVO.setBusiTypeId3(examPaperExit.getBusiTypeId3());
        examPaperDetailVO.setBusiTypeName3(examPaperExit.getBusiTypeName3());
        examPaperDetailVO.setPassScore(examPaperExit.getPassScore());
        examPaperDetailVO.setDescription(examPaperExit.getDescription());
        examPaperDetailVO.setQuestions(examQuestionVOS);
        return examPaperDetailVO;
    }

    // 批量转换 List<ExamManualQuestion> 为 List<ExamQuestionVO>
    private List<ExamQuestionVO> convertToExamQuestionVOList(List<ExamManualQuestion> examManualQuestions) {
        List<ExamQuestionVO> examQuestionVOList = new ArrayList<>();
        if (examManualQuestions != null && !examManualQuestions.isEmpty()) {
            for (ExamManualQuestion examManualQuestion : examManualQuestions) {
                ExamQuestionVO examQuestionVO = convertToExamQuestionVO(examManualQuestion);
                if (examQuestionVO != null) {
                    examQuestionVOList.add(examQuestionVO);
                }
            }
        }
        return examQuestionVOList;
    }

    // 根据 ExamManualQuestion 转换为 ExamQuestionVO
    private ExamQuestionVO convertToExamQuestionVO(ExamManualQuestion examManualQuestion) {
        if (examManualQuestion == null) {
            return null;
        }

        Integer questionId = examManualQuestion.getQsId();
        ExamQuestionBank questionBank = examQuestionBankMapper.selectById(questionId);

        if (questionBank == null) {
            return null; // 如果没有查到题目数据，则返回 null
        }

        ExamQuestionVO examQuestionVO = new ExamQuestionVO();
        examQuestionVO.setId(examManualQuestion.getId());
        examQuestionVO.setQuestionId(questionBank.getId());
        examQuestionVO.setVersion(questionBank.getVersion());
        examQuestionVO.setQuestionType(questionBank.getQuestionType());
        examQuestionVO.setBusiType1(String.valueOf(questionBank.getBusiTypeId1()));
        examQuestionVO.setBusiTypeName1(questionBank.getBusiTypeName1());
        examQuestionVO.setBusiTypeId2(questionBank.getBusiTypeId2());
        examQuestionVO.setBusiTypeName2(questionBank.getBusiTypeName2());
        examQuestionVO.setBusiTypeId3(questionBank.getBusiTypeId3());
        examQuestionVO.setLevel(Integer.valueOf(questionBank.getLevel()));
        examQuestionVO.setQsContent(questionBank.getQsContent());
        examQuestionVO.setCorrectAnsJson(questionBank.getCorrectAnsJson());
        examQuestionVO.setAnalysis(questionBank.getAnalysis());
        examQuestionVO.setQsCorrectAns(questionBank.getQsCorrectAns());
        examQuestionVO.setStatus(questionBank.getStatus());
        examQuestionVO.setQuestionOrder(examManualQuestion.getOrderNumber());
        examQuestionVO.setScore(examManualQuestionMapper.selectExamManualQuestionById(examManualQuestion.getId()).getScore());

        return examQuestionVO;
    }

    // VO 转实体类方法
    private ExamPaper convertToExamPaper(ExamPaperDTO examPaperDTO) {
        ExamPaper examPaper = new ExamPaper();
        examPaper.setId(examPaperDTO.getPaperId());
        examPaper.setName(examPaperDTO.getPaperName());
        examPaper.setBusiTypeId1(examPaperDTO.getBusiTypeId1());
        examPaper.setBusiType1(examPaperDTO.getBusiType1());
        examPaper.setBusiTypeName1(examPaperDTO.getBusiTypeName1());
        examPaper.setBusiTypeId2(examPaperDTO.getBusiTypeId2());
        examPaper.setBusiTypeName2(examPaperDTO.getBusiTypeName2());
        examPaper.setBusiTypeId3(String.valueOf(examPaperDTO.getBusiTypeId3()));
        examPaper.setBusiTypeName3(examPaperDTO.getBusiTypeName3());
        examPaper.setDescription(examPaperDTO.getDescription());
        examPaper.setQuestionType(examPaperDTO.getQuestionType());
        examPaper.setPassScore(examPaperDTO.getPassScore());
        log.info("passScore:" + examPaperDTO.getPassScore());
        return examPaper;
    }


}

